﻿using Grow.Domain.Object;
using Grow.Module.Service;

namespace Grow.Domain.Repository
{
    public abstract class DomainRepositoryBase<TAggregateRoot> : IDomainRepository<TAggregateRoot>
        where TAggregateRoot : class, IAggregateRoot
    {
        private readonly IDbContext _dbContext;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IServiceContext _serviceContext;
        protected DomainRepositoryBase(IServiceContext serviceContext)
        {
            _serviceContext = serviceContext;
            _unitOfWork = _serviceContext.GetRequiredService<IUnitOfWorkManager>().GetUnitOfWork();
            _dbContext = _unitOfWork.DbContext;
        }


        public IQueryable<TAggregateRoot> GetQueryable()
        {
            return _dbContext.GetQueryable<TAggregateRoot>();
        }

        public IQueryable<TAggregateRoot> GetQueryableAsNoTracking()
        {
            return _dbContext.GetQueryableAsNoTracking<TAggregateRoot>();
        }


        public async Task AddAsync(TAggregateRoot aggregateRoot, CancellationToken cancellationToken = default)
        {
            await _dbContext.AddAsync(aggregateRoot, cancellationToken);
        }



        public async Task RemoveAsync(TAggregateRoot aggregateRoot, CancellationToken cancellationToken = default)
        {
            await _dbContext.RemoveAsync(aggregateRoot, cancellationToken);
        }

        public async Task UpdateAsync(TAggregateRoot aggregateRoot, CancellationToken cancellationToken = default)
        {
            await _dbContext.UpdateAsync(aggregateRoot, cancellationToken);
        }

        public Task<TAggregateRoot?> FirstOrDefaultAsync(Func<TAggregateRoot, bool> whereFunc, CancellationToken cancellationToken)
        {
            return _dbContext.FirstOrDefaultAsync(GetQueryable().Where(whereFunc).AsQueryable(), cancellationToken);
        }

        public Task<List<TAggregateRoot>> ToListAsync(Func<TAggregateRoot, bool> whereFunc, CancellationToken cancellationToken)
        {
            return _dbContext.ToListAsync(GetQueryable().Where(whereFunc).AsQueryable(), cancellationToken);
        }

        public Task<List<TAggregateRoot>> ToListAsync(Func<TAggregateRoot, bool> whereFunc, int maxCount, CancellationToken cancellationToken)
        {
            return _dbContext.ToListAsync(GetQueryable().Where(whereFunc).Take(maxCount).AsQueryable(), cancellationToken);
        }
    }
}
